package com.md.base;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.md.config.database.CustomMapper;
import com.md.value.constants.NumberConstants;
import com.md.value.enums.EnableEnum;
import lombok.Getter;
import org.springframework.lang.NonNull;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;

/**
 * @author 刘骄阳
 * 2022-06-12 1:33
 */
@Getter
public class BaseRepositoryImpl<T extends BasePO, E extends CustomMapper<T>> implements BaseRepository<T> {
  protected final E mapper;

  public BaseRepositoryImpl(final E mapper) {
    this.mapper = mapper;
  }

  /**
   * 新增
   *
   * @param t 请求实体
   * @return 操作结果
   */
  @Override
  public Integer insert(final T t) {
    return mapper.insert(t);
  }

  /**
   * 批量添加
   *
   * @param list 实体列表
   */
  @Override
  public void insertBatch(final @NonNull Collection<T> list) {
    if (ObjectUtils.isEmpty(list)) {
      return;
    }
    mapper.insertBatchSomeColumn(list);
  }

  /**
   * 根据主键删除
   *
   * @param id 主键id
   * @return 操作结果
   */
  @Override
  public Integer delete(final Serializable id) {
    LambdaUpdateWrapper<T> wrapper = new LambdaUpdateWrapper<>();
    wrapper.eq(T::getId, id).set(T::getIsDeleted, EnableEnum.DISABLE.getCode())
      .set(T::getUpdateDate, LocalDateTime.now());
    return mapper.update(null, wrapper);
  }

  /**
   * 删除
   *
   * @param t 实体
   * @return 操作结果
   */
  @Override
  public Integer delete(final T t) {
    LambdaUpdateWrapper<T> wrapper = new LambdaUpdateWrapper<>(t);
    wrapper.set(T::getIsDeleted, EnableEnum.DISABLE.getCode()).set(T::getUpdateDate, LocalDateTime.now());
    return mapper.update(null, wrapper);
  }

  /**
   * 批量删除
   *
   * @param ids id列表
   * @return 操作结果
   */
  @Override
  public Integer deleteBatch(final List<Serializable> ids) {
    if (CollectionUtils.isEmpty(ids)) {
      return NumberConstants.ZERO.getIntCode();
    }
    LambdaUpdateWrapper<T> wrapper = new LambdaUpdateWrapper<>();
    wrapper.in(T::getId, ids).set(T::getIsDeleted, EnableEnum.DISABLE.getCode())
      .set(T::getUpdateDate, LocalDateTime.now());
    return mapper.update(null, wrapper);
  }

  /**
   * 修改
   *
   * @param t 实体
   * @return 操作结果
   */
  @Override
  public Integer update(final T t) {
    return mapper.updateById(t);
  }

  /**
   * 分页查询
   *
   * @param t        实体
   * @param pageNum  行数
   * @param pageSize 页数
   * @return 操作结果
   */
  @Override
  public IPage<T> selectPage(final T t, final Long pageNum, final Long pageSize) {
    return mapper.selectPage(new Page<>(pageNum, pageSize), new LambdaQueryWrapper<>(t));
  }

  /**
   * 查询
   *
   * @param t 实体
   * @return 操作结果
   */
  @Override
  public T select(final T t) {
    LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>(t);
    wrapper.orderByDesc(T::getId).last("limit 1");
    return mapper.selectOne(wrapper);
  }

  /**
   * 批量查询
   *
   * @param t 实体
   * @return 操作结果
   */
  @Override
  public List<T> selectList(final T t) {
    // todo 追加order条件
    return mapper.selectList(new LambdaQueryWrapper<>(t));
  }

  /**
   * 查询全部
   *
   * @return 操作结果
   */
  @Override
  public List<T> selectAll() {
    return mapper.selectList(new LambdaQueryWrapper<>());
  }

  /**
   * 根据id查询
   *
   * @param id 主键ID
   * @return 操作结果
   */
  @Override
  public T selectById(final Serializable id) {
    return mapper.selectById(id);
  }

  /**
   * 根据id批量查询
   *
   * @param ids 主键ID集合
   * @return 操作结果
   */
  @Override
  public List<T> selectByIds(final Collection<Long> ids) {
    if (ObjectUtils.isEmpty(ids)) {
      return Lists.newArrayList();
    }
    LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
    wrapper.in(T::getId, ids);
    return mapper.selectList(wrapper);
  }

  /**
   * 校验数据是否存在
   *
   * @param t 实体
   * @return 校验是否存在(true : 存在 ; false : 不存在)
   */
  @Override
  public boolean hasExists(final T t) {
    LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>(t);
    wrapper.select(T::getId);
    return mapper.exists(wrapper);
  }
}
